-
Notifications
You must be signed in to change notification settings - Fork 365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8422 list multipart uploads #8531
base: master
Are you sure you want to change the base?
Conversation
🎊 PR Preview 7b1500d has been successfully built and deployed to https://treeverse-lakeFS-preview-pr-8531.surge.sh 🕐 Build time: 0.01s 🤖 By surge-preview |
@ItamarYuran Can you please make sure the CI passes first? 🙏 |
ce35f96
to
47a576e
Compare
47a576e
to
cff37f2
Compare
Note - the marker works only when using both key marker & upload is marker. The key marker uses the physical address to mark the pagination. The physical address of the marked upload is of course returned as well when there are uploads left for next pagination. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm taking a step back and looking on the request which accepts Path and KeyMarker.
The underlaying storage can't provide this information as it holds the physical address and not the logical path the user provides.
I suggest having a test / use-case that test this code first to provide a working solution.
Implementation wise - it means that the information can be tracked and it means you will need this capability from the tracker. and in this case consider adding it to all the adapters and not specific s3 feature.
Update our (@ItamarYuran and myself) conversion output:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a few minor comments, but overall, it looks good!
esti/s3_gateway_test.go
Outdated
// unsupported headers, expect error | ||
delimiter := aws.String("/") | ||
prefix := aws.String("prefix") | ||
encodingType := types.EncodingTypeUrl | ||
|
||
output, err = s3Client.ListMultipartUploads(ctx, &s3.ListMultipartUploadsInput{Bucket: resp1.Bucket, Delimiter: delimiter}) | ||
require.Error(t, err) | ||
require.Contains(t, err.Error(), "NotImplemented") | ||
|
||
output, err = s3Client.ListMultipartUploads(ctx, &s3.ListMultipartUploadsInput{Bucket: resp1.Bucket, Prefix: prefix}) | ||
require.Error(t, err) | ||
require.Contains(t, err.Error(), "NotImplemented") | ||
|
||
output, err = s3Client.ListMultipartUploads(ctx, &s3.ListMultipartUploadsInput{Bucket: resp1.Bucket, EncodingType: encodingType}) | ||
require.Error(t, err) | ||
require.Contains(t, err.Error(), "NotImplemented") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these checks should be in a different test @nopcoder WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in general you are right but because we are going to skip this one for now for control-plane, might be nice to keep it in one spot. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that the multipart upload was the only test that we used esti to check as it requires 5M uploads per part.
Agree with Idean - this part can be part the adapter package test as it should represent the spec we supprot.
pkg/gateway/errors/errors.go
Outdated
@@ -204,6 +205,11 @@ func (a APIErrorCode) ToAPIErr() APIError { | |||
// Codes - error code to APIError structure, these fields carry respective | |||
// descriptions for all the error responses. | |||
var Codes = errorCodeMap{ | |||
ErrInvalidArgument: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This name is too generic for this error.
If I wouldn't read the description I could use this error in other places.
Maybe call it ErrInvalidMaxUploads
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the err i got from s3 while trying it with bad input
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I missed this one - The problem is not with the generic name is the format of the message and how we map the errors in the gateway.
Each error is mapped latest inside:
// Codes - error code to APIError structure, these fields carry respective
// descriptions for all the error responses.
var Codes = errorCodeMap
Map the specific error message and add it into both places.
NextKeyMarker: *mpuResp.NextKeyMarker, | ||
NextUploadIDMarker: *mpuResp.NextUploadIDMarker, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the AWS's helper function to get the value and check if the value is not nil - aws.StringValue
pkg/gateway/serde/xml.go
Outdated
NextKeyMarker string `xml:"NextKeyMarker"` | ||
NextUploadIDMarker string `xml:"NextUploadIDMarker"` | ||
IsTruncated bool `xml:"IsTruncated"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please verify that if there is no pagination required, does S3 remove these fields - which means that we need to set them as omitempty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in case there is no pagination, itTruncated does not appear in s3's answer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is why we should use omitempty
maxUploads32 := int32(maxUploads) | ||
opts.MaxUploads = &maxUploads32 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- We didn't verified that the value is 0-1000
- Condition settings MaxUploads is above 0. The use of pointers in the AWS APIs is specify optionals and in case we do not pass values, we should use the same while working with the underlying SDK (at least try when it makes sense)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now aligned with s3, the input is checked and expects a value between 0-2147483647. other values will raise s3's err
@@ -289,6 +289,134 @@ func TestS3IfNoneMatch(t *testing.T) { | |||
} | |||
} | |||
|
|||
func TestListMultipartUploads(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test should run only on S3 - I assume that the tests didn't pass for azure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As @idanovo asked, these tests run for other adapters as well, only until the the first list mpu request in which they are expected to fail. then they are being skipped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nopcoder I wanted to make sure we get the right error for other block stores
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, but I don't understand how it works as we currently do not support this flow for all adapters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if blockStoreType != "s3" {
require.Contains(t, err.Error(), "NotImplemented")
return
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I see the check down the code of this function - but why do we even start to upload if we can't test it on non-s3 implementation?
we have a different test to check missing functionality
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be tested in another test.
@ItamarYuran, my suggestion is to:
- Change
TestListMultipartUploads
TestListMultipartUploadsUnsupported
back to t.skipp with a proper messageif blockStoreType != "s3"
- Change
TestListMultipartUploadsUnsupported
name to indicate it checks only unsupported parameters - Add another test that only checks that ListMultipartUpload returns the right error
if blockStoreType != "s3"
@nopcoder WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
think that the latest change include the above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't
- We are returning and not skipping
- We don't test the error we get for object storage that are not s3
esti/s3_gateway_test.go
Outdated
|
||
} | ||
func TestListMultipartUploadsUnsupported(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | |
func TestListMultipartUploadsUnsupported(t *testing.T) { | |
} | |
func TestListMultipartUploadsUnsupported(t *testing.T) { |
esti/s3_gateway_test.go
Outdated
delimiter := aws.String("/") | ||
prefix := aws.String("prefix") | ||
encodingType := types.EncodingTypeUrl | ||
|
||
_, err := s3Client.ListMultipartUploads(ctx, &s3.ListMultipartUploadsInput{Bucket: Bucket, Delimiter: delimiter}) | ||
require.Error(t, err) | ||
require.Contains(t, err.Error(), "NotImplemented") | ||
|
||
_, err = s3Client.ListMultipartUploads(ctx, &s3.ListMultipartUploadsInput{Bucket: Bucket, Prefix: prefix}) | ||
require.Error(t, err) | ||
require.Contains(t, err.Error(), "NotImplemented") | ||
|
||
_, err = s3Client.ListMultipartUploads(ctx, &s3.ListMultipartUploadsInput{Bucket: Bucket, EncodingType: encodingType}) | ||
require.Error(t, err) | ||
require.Contains(t, err.Error(), "NotImplemented") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- As far as I remember we don't capture unsupported states. Wonder if need this extra test as we don't do it for all the adapters.
- Can use t.Run to capture each state
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please address all @nopcoder's comments before merging 🙏
maxUploadsListMPU = 2147483647 | ||
minUploadsListMPU = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
if we leave the verification to the underlaying library - you can remove maxUploadsListMPU - it is MaxInt32 value and it will not pass this value as the cast will not let you.
-
if we plan to pass 0 as a valid value and let the underlying package handle it - we just need to check if maxUploads32 < 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Closes #8422
Introducing List Multiupart uploads command to the s3 gateway.
example command:
✗ aws s3api --endpoint-url=http://127.0.0.1:8000/ list-multipart-uploads --bucket itamar --profile default
This will return all multipart uploads (upload id and path) that are held by the tracker.